﻿using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace OpenData.Framework
{
    public class MongoSchemaRepository : Schema, ISchemaRepository
    {
        string connectionString;
        public string SchemaName { get; set; }
        readonly string dbName = "SYSTEMSCHEMA";
        public MongoSchemaRepository(string connectionString, string entityName)
            : base(entityName, null)
        {
            this.connectionString = connectionString;
            this.SchemaName = entityName;
            foreach (var item in this.SystemColumns)
            {
                InsertColumn(item);
            }
        }

        public IEnumerable<Column> QueryColumn()
        {
            var client = new MongoClient();
            var db = client.GetDatabase(this.connectionString);
            var filter = Builders<BsonDocument>.Filter.Eq("EntityName", this.SchemaName);
            var sort = Builders<BsonDocument>.Sort.Ascending("_id");
            var collection = db.GetCollection<BsonDocument>(this.dbName);
            var result = collection.Find(filter).Sort(sort).ToListAsync().GetAwaiter().GetResult();

            foreach (var column in result)
            {

                var entity = new Column()
                {
                    Name = column["Name"].ToString(),
                    IsSystemField = column["IsSystemField"].ToBoolean(),
                    Indexable = column["Indexable"].ToBoolean(),
                    Tooltip = column["Tooltip"].ToString(),
                    Summarize = column["Summarize"].ToBoolean(),
                    ShowInGrid = column["ShowInGrid"].ToBoolean(),
                    AllowNull = column["AllowNull"].ToBoolean(),
                    Order = column["Order"].ToInt32(),
                    DefaultValue = column["DefaultValue"].ToString(),
                    Label = column["Label"].ToString(),
                    SelectionFolder = column["SelectionFolder"].ToString(),
                    ControlType = column["ControlType"].ToString(),
                    //CustomSettings = column["CustomSettings"],
                    Length = column["Length"].ToInt32(),
                    Modifiable = column["Modifiable"].ToBoolean(),

                };
                this.AddColumn(entity);
            }
            return this.AllColumns;
        }

        public void InsertColumn(Column column)
        {
            if (this.AddColumn(column))
            {
                var client = new MongoClient();
                var db = client.GetDatabase(this.connectionString);
                var collection = db.GetCollection<BsonDocument>(this.dbName);
                if (null != collection.Find(m => m["Name"] == column.Name).FirstOrDefaultAsync().GetAwaiter().GetResult())
                {
                    return;
                }

                var insert = new BsonDocument();
                insert.Add("EntityName", BsonValue.Create(this.SchemaName));

                insert.Add("Name", BsonValue.Create(column.Name));
                insert.Add("IsSystemField", BsonValue.Create(column.IsSystemField));
                insert.Add("Indexable", BsonValue.Create(column.Indexable));
                insert.Add("Tooltip", BsonValue.Create(column.Tooltip));
                insert.Add("Summarize", BsonValue.Create(column.Summarize));
                insert.Add("ShowInGrid", BsonValue.Create(column.ShowInGrid));
                insert.Add("AllowNull", BsonValue.Create(column.AllowNull));
                insert.Add("Order", BsonValue.Create(column.Order));
                insert.Add("DefaultValue", BsonValue.Create(column.DefaultValue));
                insert.Add("Label", BsonValue.Create(column.Label));
                insert.Add("SelectionFolder", BsonValue.Create(column.SelectionFolder));
                insert.Add("ControlType", BsonValue.Create(column.ControlType));
                //insert.Add("CustomSettings",column.CustomSettings);
                insert.Add("Length", BsonValue.Create(column.Length));
                insert.Add("Modifiable", BsonValue.Create(column.Modifiable));

                var result = collection.InsertOneAsync(insert);
            }
        }

        public void DeleteColumn(Column column)
        {
            if (base.RemoveColumn(column) > 0)
            {
                var client = new MongoClient();
                var db = client.GetDatabase(this.connectionString);
                var collection = db.GetCollection<BsonDocument>(this.dbName);
                var filter = Builders<BsonDocument>.Filter.Eq("Name", column.Name);
                filter &= Builders<BsonDocument>.Filter.Eq("EntityName", this.SchemaName);
                var result = collection.DeleteOneAsync(filter);
            }
        }
    }
}